package com.yunquan.ohana.utils


import android.util.Patterns
import java.net.IDN
import java.util.*
import java.util.regex.Pattern

/**
 * 字符串操作工具类$
 * @author yjp
 * @date 2020/3/31 10:10
 */
object StringUtils {
    /**
     * 邮箱效验
     */
    fun isEmail(email: String?): Boolean {
        if (email.isNullOrBlank()) return false

        // 快速排除空格等明显错误
        val trimmed = email.trim()
        if (trimmed.length > 320) return false   // RFC 限制（近似）
        // 必须且只有一个 '@'
        val atCount = trimmed.count { it == '@' }
        if (atCount != 1) return false

        // 将域名部分转为 ASCII (Punycode)，以支持国际化域名
        val parts = trimmed.split('@', limit = 2)
        val local = parts[0]
        val domain = parts[1]
        if (local.isEmpty() || domain.isEmpty()) return false

        val asciiDomain = try {
            IDN.toASCII(domain)
        } catch (e: Exception) {
            return false
        }

        val normalized = "$local@$asciiDomain"

        // 使用 Android 提供的 Patterns.EMAIL_ADDRESS 来判断
        return Patterns.EMAIL_ADDRESS.matcher(normalized).matches()
    }

    /**
     * 判断字符串是否为空
     *
     * @param str : 需要判断的字符串
     * @return Boolean
     */
    fun isEmpty(s: String?): Boolean {
        var str = s
        str = delInvisibleChar(str)
        return str.isEmpty() || (str == "")
    }

    /**
     * 剔除不可见字符串
     *
     * @param str : 需要处理的字符串
     * @return String
     */
    fun delInvisibleChar(str: String?): String {
        return str?.replace("[ \n\r\t]".toRegex(), "") ?: ""
    }

    /**
     * 判断字符串是否为null或全为空格
     *
     * @param s 待校验字符串
     * @return `true`: null或全空格<br></br> `false`: 不为null且不全空格
     */
    fun isTrimEmpty(s: String?): Boolean {
        return s == null || s.trim { it <= ' ' }.isEmpty()
    }

    /**
     * 判断字符串是否为null或全为空白字符
     *
     * @param s 待校验字符串
     * @return `true`: null或全空白字符<br></br> `false`: 不为null且不全空白字符
     */
    fun isSpace(s: String?): Boolean {
        if (s == null) return true
        var i = 0
        val len = s.length
        while (i < len) {
            if (!Character.isWhitespace(s[i])) {
                return false
            }
            ++i
        }
        return true
    }

    /**
     * 判断两字符串是否相等
     *
     * @param a 待校验字符串a
     * @param b 待校验字符串b
     * @return `true`: 相等<br></br>`false`: 不相等
     */
    fun equals(a: CharSequence?, b: CharSequence?): Boolean {
        if (a == b) return true
        return if (a != null && b != null && a.length == b.length) {
            val length = a.length
            if (a is String && b is String) {
                a == b
            } else {
                for (i in 0 until length) {
                    if (a[i] != b[i]) return false
                }
                true
            }
        } else false
    }

    /**
     * 判断两字符串忽略大小写是否相等
     *
     * @param a 待校验字符串a
     * @param b 待校验字符串b
     * @return `true`: 相等<br></br>`false`: 不相等
     */
    fun equalsIgnoreCase(a: String?, b: String?): Boolean {
        return a?.equals(b, ignoreCase = true) ?: (b == null)
    }

    /**
     * null转为长度为0的字符串
     *
     * @param s 待转字符串
     * @return s为null转为长度为0字符串，否则不改变
     */
    fun null2Length0(s: String?): String? {
        return s ?: ""
    }

    /**
     * 返回字符串长度
     *
     * @param s 字符串
     * @return null返回0，其他返回自身长度
     */
    fun length(s: CharSequence?): Int {
        return s?.length ?: 0
    }

    /**
     * 判断字符串中是否包含大写字符
     */
    fun isUpperCase(s: String): Boolean {
        return Pattern.compile(".*[A-Z]+.*").matcher(s).matches()
    }

    /**
     * 查找字符串中大写字符的个数
     */
    fun findUpperCaseCount(s: String): Int {
        return if (isUpperCase(s)) {
            val m = Pattern.compile("[A-Z]+").matcher(s)
            var endIndex = 0;
            var count = 0;
            while (m.find(endIndex)) {
                println(m.start())
                println(m.group())
                endIndex = m.end()
                count++
            }
            count
        } else {
            -1
        }
    }

    /**
     * 把字符串中的大写字母转小写并在前加“_”
     */
    fun toLowerCaseName(s: String): String {
        val m = Pattern.compile("[A-Z]").matcher(s)
        var endIndex = 0;
        var temp = s;
        while (m.find(endIndex)) {
            val index = temp.indexOf(m.group())
            val str = temp.substring(index, index + 1);
            temp = temp.substring(
                0,
                index
            ) + "_" + str.lowercase(Locale.ROOT) + temp.substring(index + 1)
            endIndex = m.end()
        }
        if (temp.startsWith("_")) {
            temp = temp.substring(1)
        }
        println(temp)
        return temp
    }


    /**
     * 首字母大写
     *
     * @param s 待转字符串
     * @return 首字母大写字符串
     */
    fun upperFirstLetter(s: String): String {
        return if (!Character.isLowerCase(s[0])) s
        else (s[0].toInt() - 32).toChar() + s.substring(1)
    }

    /**
     * 首字母小写
     *
     * @param s 待转字符串
     * @return 首字母小写字符串
     */
    fun lowerFirstLetter(s: String): String {
        return if (!Character.isUpperCase(s[0])) s
        else (s[0].toInt() + 32).toChar() + s.substring(1)
    }

    /**
     * 反转字符串
     *
     * @param s 待反转字符串
     * @return 反转字符串
     */
    fun reverse(s: String): String? {
        val len: Int = length(s)
        if (len <= 1) return s
        val mid = len shr 1
        val chars = s.toCharArray()
        var c: Char
        for (i in 0 until mid) {
            c = chars[i]
            chars[i] = chars[len - i - 1]
            chars[len - i - 1] = c
        }
        return String(chars)
    }

    /**
     * 转化为半角字符
     *
     * @param s 待转字符串
     * @return 半角字符串
     */
    fun toDBC(s: String): String {
        if (isEmpty(s)) return s
        val chars = s.toCharArray()
        var i = 0
        val len = chars.size
        while (i < len) {
            when {
                chars[i].toInt() == 12288 -> {
                    chars[i] = ' '
                }

                chars[i].toInt() in 65281..65374 -> {
                    chars[i] = (chars[i] - 65248)
                }

                else -> {
                    chars[i] = chars[i]
                }
            }
            i++
        }
        return String(chars)
    }

    /**
     * 转化为全角字符
     *
     * @param s 待转字符串
     * @return 全角字符串
     */
    fun toSBC(s: String): String {
        if (isEmpty(s)) return s
        val chars = s.toCharArray()
        var i = 0
        val len = chars.size
        while (i < len) {
            when {
                chars[i] == ' ' -> {
                    chars[i] = 12288.toChar()
                }

                chars[i].toInt() in 33..126 -> {
                    chars[i] = (chars[i] + 65248)
                }

                else -> {
                    chars[i] = chars[i]
                }
            }
            i++
        }
        return String(chars)
    }

    /**
     * 驼峰属性名转大写加下划线分隔
     * @param name
     */
    fun getColumnName(name: String): String {
        val sb = StringBuilder()
        val chars = name.toCharArray()
        for (i in chars.indices) {
            if (chars[i] in 'A'..'Z') {
                sb.append("_").append(chars[i])
            } else {
                sb.append(chars[i])
            }
        }
        return sb.toString().uppercase(Locale.ROOT)
    }

    /**
     * 列名转驼峰属性名
     *
     * @param name : 列名
     * @return 属性名
     */
    fun getPropertyName(name: String): String {
        val sb = StringBuilder()
        val chars = name.toCharArray()
        var i = 0
        while (i < chars.size) {
            if (chars[i] != '_') {
                i++
                sb.append(chars[i])
            } else {
                sb.append(chars[i] + 32)
            }
            i++
        }
        return sb.toString()
    }

    /**
     * 判断传入的字符串是否是double型
     *
     * @param s
     * @return
     */
    fun isDouble(s: String): Boolean {
        return s.matches(Regex("^[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$"))
    }

    /**
     * 字符串转Double
     */
    fun getDouble(s: String?): Double {
        return when {
            isEmpty(s) -> {
                0.0
            }

            isDouble(s!!) -> {
                s.toDouble()
            }

            else -> {
                0.0
            }
        }
    }

    /**
     * 判断传入的字符串是不是正整数
     *
     * @param s
     * @return
     */
    fun isNumber(s: String): Boolean {
        return s.matches(Regex("^[1-9]\\d*$"))
    }

    /**
     * 字符串转整数
     */
    fun getNumber(s: String?): Int {
        return when {
            isEmpty(s) -> {
                0
            }

            isNumber(s!!) -> {
                s.toInt()
            }

            isDouble(s) -> {
                val end = s.substring(s.indexOf(".") + 1)
                if (isNumber(end) && end.toInt() == 0) {
                    s.substring(0, s.indexOf(".")).toInt()
                } else {
                    0
                }
            }

            else -> {
                0
            }
        }
    }

    /**
     * 判断传入的字符串是不是数字,带小数点
     *
     * @param s
     * @return
     */
    fun isDigital(s: String): Boolean {
        return isDouble(s) || isNumber(s)
    }
}